package cn.wxz1997.permission.service.impl;

import cn.wxz1997.permission.dao.PermissionMapper;
import cn.wxz1997.permission.dao.RolePermissionMapper;
import cn.wxz1997.permission.dto.PermissionMenuDTO;
import cn.wxz1997.permission.pojo.Permission;
import cn.wxz1997.permission.service.PermissionService;
import cn.wxz1997.permission.util.Result;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import lombok.extern.slf4j.Slf4j;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @Description: ${todo}
 * @Author: wxz1997
 * @Date 18-8-10下午3:49
 */
@Slf4j
@Service
public class PermissionServiceImpl implements PermissionService{

    private static final String ROOT = "0";

    @Autowired
    private PermissionMapper permissionMapper;

    @Autowired
    private RolePermissionMapper rolePermissionMapper;

    @Autowired
    private ModelMapper modelMapper;

    @Override
    public List<PermissionMenuDTO> getMenuTree(Integer userId) {
        List<Permission> permissions = permissionMapper.selectByUserId(userId);
        return getTree(permissions);
    }

    @Override
    public List<PermissionMenuDTO> getPermissionTree() {
        List<Permission> permissions = permissionMapper.selectAll();
        return getTree(permissions);
    }

    @Override
    public List<Permission> list() {
        return permissionMapper.selectAll();
    }

    @Override
    public Permission add(Permission permission) {
        if (permission.getParentId() == 0){
            permission.setLevel(ROOT);
        }else {
            Permission parent = permissionMapper.selectByPrimaryKey(permission.getParentId());
            permission.setLevel(parent.getLevel() + "." + parent.getId());
        }
        permission.setCreateTime(new Date());
        permissionMapper.insertSelective(permission);
        return permissionMapper.selectByPrimaryKey(permission.getId());
    }

    @Override
    public Permission selectById(Integer id) {
        return permissionMapper.selectByPrimaryKey(id);
    }

    @Override
    public Permission update(Permission permission) {
        if (permission.getParentId() == 0){
            permission.setLevel(ROOT);
        }else {
            Permission parent = permissionMapper.selectByPrimaryKey(permission.getParentId());
            permission.setLevel(parent.getLevel() + "." + parent.getId());
        }
        permissionMapper.updateByPrimaryKeySelective(permission);
        return permissionMapper.selectByPrimaryKey(permission.getId());
    }

    @Override
    public Integer delete(Integer id) {
        rolePermissionMapper.deleteByRoleId(id);
        return permissionMapper.deleteByPrimaryKey(id);
    }

    private List<PermissionMenuDTO> getTree(List<Permission> permissions){
        Multimap<String, PermissionMenuDTO> levelMap = ArrayListMultimap.create();

        for (Permission permission: permissions){
            PermissionMenuDTO permissionMenuDTO = modelMapper.map(permission, PermissionMenuDTO.class);
            levelMap.put(permission.getLevel(), permissionMenuDTO);
        }

        return permissionMenuDTOTree(levelMap, ROOT);
    }

    private List<PermissionMenuDTO> permissionMenuDTOTree(Multimap<String, PermissionMenuDTO> levelMap, String level) {

        List<PermissionMenuDTO> currentList = (List<PermissionMenuDTO>) levelMap.get(level);

        if (currentList.isEmpty()){
            return null;
        }

        List<PermissionMenuDTO> targetList = new ArrayList<>();

        for (PermissionMenuDTO permissionMenuDTO: currentList){
            String nextLevel = level + "." + permissionMenuDTO.getId();
            permissionMenuDTO.setChildren(permissionMenuDTOTree(levelMap, nextLevel));
            targetList.add(permissionMenuDTO);
        }

        return targetList;
    }
}
